package com.commerce.product.service.impl;

import com.commerce.common.entity.Product;
import com.commerce.common.utils.Result;
import com.commerce.order.config.RabbitMQConfig;
import com.commerce.order.feign.ProductFeignClient;
import com.commerce.product.service.ProductService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 产品服务实现类
 */
@Service
public class ProductServiceImpl implements ProductService {
    private static final Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);
    
    @Autowired
    private ProductFeignClient productFeignClient;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    // 用于存储异步获取的产品信息
    private final Map<Long, Product> productCache = new ConcurrentHashMap<>();
    private final Map<Long, CountDownLatch> latchMap = new ConcurrentHashMap<>();
    
    @PreDestroy
    public void destroy() {
        try {
            // 等待所有进行中的操作完成
            for (CountDownLatch latch : latchMap.values()) {
                try {
                    latch.countDown();
                } catch (Exception ignored) {
                }
            }
            // 清理资源
            productCache.clear();
            latchMap.clear();
        } catch (Exception e) {
            logger.error("销毁ProductService时发生错误", e);
        }
    }
    
    @Override
    public Product getProductById(Long id) {
        try {
            // 首先尝试使用Feign同步调用
            Result<Product> result = productFeignClient.getProductById(id);
            if (result != null && result.isSuccess()) {
                return result.getData();
            }
        } catch (Exception e) {
            logger.warn("通过Feign获取产品信息失败: {}", e.getMessage());
        }

        // Feign调用失败，返回一个默认的商品信息以避免订单创建失败
        logger.warn("无法获取商品信息，使用默认商品信息: productId={}", id);
        Product defaultProduct = new Product();
        defaultProduct.setId(id);
        defaultProduct.setName("商品信息获取失败");
        defaultProduct.setMainImage("/default-product.jpg");
        defaultProduct.setPrice(new java.math.BigDecimal("0.00"));
        defaultProduct.setStock(0);
        return defaultProduct;
    }
    
    @Override
    public List<Product> getProductsByIds(List<Long> ids) {
        try {
            // 首先尝试使用Feign同步调用
            Result<List<Product>> result = productFeignClient.getProductsByIds(ids);
            if (result != null && result.isSuccess()) {
                return result.getData();
            }
        } catch (Exception e) {
            logger.warn("通过Feign批量获取产品信息失败: {}", e.getMessage());
        }

        // Feign调用失败，为每个ID返回默认商品信息
        List<Product> products = new ArrayList<>();
        for (Long id : ids) {
            Product defaultProduct = new Product();
            defaultProduct.setId(id);
            defaultProduct.setName("商品信息获取失败");
            defaultProduct.setMainImage("/default-product.jpg");
            defaultProduct.setPrice(new java.math.BigDecimal("0.00"));
            defaultProduct.setStock(0);
            products.add(defaultProduct);
        }
        return products;
    }

    @Override
    public void updateById(Product product) {
        // 实现产品更新逻辑
    }

    private Product getProductByIdWithRabbitMQ(Long id) {
        try {
            // 清除之前的缓存
            productCache.remove(id);
            
            // 创建等待锁
            CountDownLatch latch = new CountDownLatch(1);
            latchMap.put(id, latch);
            
            // 发送消息到产品服务
            rabbitTemplate.convertAndSend(
                RabbitMQConfig.PRODUCT_EXCHANGE,
                RabbitMQConfig.PRODUCT_GET_ROUTING_KEY,
                id.toString()
            );
            
            // 等待结果返回，最多等待3秒
            boolean received = latch.await(3, TimeUnit.SECONDS);
            
            // 移除等待锁
            latchMap.remove(id);
            
            if (received) {
                // 获取并移除缓存的产品信息
                return productCache.remove(id);
            } else {
                logger.error("获取产品信息超时: {}", id);
                return null;
            }
        } catch (Exception e) {
            logger.error("使用RabbitMQ获取产品信息失败: {}", e.getMessage());
            return null;
        }
    }
    
    @RabbitListener(queues = RabbitMQConfig.PRODUCT_GET_RESULT_QUEUE, containerFactory = "rabbitListenerContainerFactory")
    public void handleProductResult(Message message) {
        try {
            // 解析产品信息
            String json = new String(message.getBody());
            Product product = objectMapper.readValue(json, Product.class);
            
            if (product != null && product.getId() != null) {
                // 缓存产品信息
                productCache.put(product.getId(), product);
                
                // 通知等待线程
                CountDownLatch latch = latchMap.get(product.getId());
                if (latch != null) {
                    latch.countDown();
                }
            }
        } catch (Exception e) {
            logger.error("处理产品信息结果失败: {}", e.getMessage());
        }
    }
} 